/**
 *    Copyright (c) 2014-2019 CK.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package com.github.fartherp.framework.common.util;

import org.apache.commons.lang3.StringUtils;

/**
 * 根据 user agent string 判断用户的平台、浏览器 参考资料
 * ****************************************
 * **************************************
 * ********************************************************************
 *
 * 台式机
 *
 * Linux Ubuntu Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.2pre)
 * Gecko/20100225 Ubuntu/9.10 (karmic) Namoroka/3.6.2pre
 * ------------------------
 * ------------------------------------------------------
 * -------------------------------------------------------------------- Linux
 * Mandriva 2008.1 Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1)
 * Gecko/2008072403 Mandriva/3.0.1-1mdv2008.1 (2008.1) Firefox/3.0.1
 * ------------
 * ------------------------------------------------------------------
 * -------------------------------------------------------------------- Linux
 * suSE 10.1 Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.3) Gecko/20060425
 * SUSE/1.5.0.3-7 Firefox/1.5.0.31
 * ----------------------------------------------
 * --------------------------------
 * -------------------------------------------------------------------- Windows
 * XP SP3 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1)
 * Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)
 * ------------------------------
 * ------------------------------------------------
 * -------------------------------------------------------------------- Windows
 * Vista Mozilla/5.0 (Windows; U; Windows NT 6.1; nl; rv:1.9.2.13)
 * Gecko/20101203 Firefox/3.6.13 Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US;
 * rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 (.NET CLR 3.5.30729)
 * ----------------
 * --------------------------------------------------------------
 * -------------------------------------------------------------------- windows
 * 2000 Mozilla/5.0 (Windows; U; Windows NT 5.0; en-GB; rv:1.8.1b2)
 * Gecko/20060821 Firefox/2.0b2
 * --------------------------------------------------
 * ----------------------------
 * -------------------------------------------------------------------- Windows
 * 7 Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1
 * --
 * ----------------------------------------------------------------------------
 * -------------------------------------------------------------------- Windows
 * Server 2008 Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5)
 * Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
 * ----------------------------
 * --------------------------------------------------
 * -------------------------------------------------------------------- iMac OSX
 * 10.7.4 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:13.0) Gecko/20100101
 * Firefox/13.0.1
 * ----------------------------------------------------------------
 * --------------
 * -------------------------------------------------------------------- Mac OS X
 * Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.9)
 * Gecko/20100824 Firefox/3.6.9
 * --------------------------------------------------
 * ----------------------------
 * --------------------------------------------------------------------
 *
 * 手持设备
 *
 * iPad Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us)
 * AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b
 * Safari/531.21.10
 * --------------------------------------------------------------
 * ----------------
 * -------------------------------------------------------------------- iPad 2
 * Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X; en-us) AppleWebKit/534.46
 * (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3
 * ----------------
 * --------------------------------------------------------------
 * -------------------------------------------------------------------- iPhone 4
 * Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us)
 * AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293
 * Safari/6531.22.7
 * --------------------------------------------------------------
 * ----------------
 * -------------------------------------------------------------------- iPhone 5
 * Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46
 * (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3
 * ----------------
 * --------------------------------------------------------------
 * -------------------------------------------------------------------- Android
 * Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91)
 * AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
 * ********
 * **********************************************************************
 * ********************************************************************
 * @author CK
 * @date 2015/9/22
 */
public class UserAgentUtil {
    /**
     * WINDOWS平台
     */
    public static final String PLATFORM_WINDOWS = "Windows";

    /**
     * IE浏览器
     */
    public static final String BROWSER_IE = "Internet Explorer";

    /**
     * CHROME浏览器
     */
    public static final String BROWSER_CHROME = "Chrome";

    /**
     * FIREFOX浏览器
     */
    public static final String BROWSER_FIREFOX = "Firefox";

    /**
     * 用途：根据客户端 User Agent Strings 判断其浏览器、操作平台 if 判断的先后次序：
     * 根据设备的用户使用量降序排列，这样对于大多数用户来说可以少判断几次即可拿到结果： >>操作系统:Windows > 苹果 > 安卓 > Linux
     * > ... >>Browser:Chrome > FF > IE > ...
     *
     * @param userAgentStr
     *            从浏览器的请求中得到USERAGENT
     * @return UserAgent对象
     */
    public static UserAgent getUserAgent(String userAgentStr) {
        if (StringUtils.isBlank(userAgentStr)) {
            return null;
        }
        if (userAgentStr.contains(PLATFORM_WINDOWS)) { // 主流应用靠前
            /**
             * ****************** 台式机 Windows 系列 ****************** Windows NT
             * 6.2 - Windows 8 Windows NT 6.1 - Windows 7 Windows NT 6.0 -
             * Windows Vista Windows NT 5.2 - Windows Server 2003; Windows XP
             * x64 Edition Windows NT 5.1 - Windows XP Windows NT 5.01 - Windows
             * 2000, Service Pack 1 (SP1) Windows NT 5.0 - Windows 2000 Windows
             * NT 4.0 - Microsoft Windows NT 4.0 Windows 98; Win 9x 4.90 -
             * Windows Millennium Edition (Windows Me) Windows 98 - Windows 98
             * Windows 95 - Windows 95 Windows CE - Windows CE
             * 判断依据:http://msdn.microsoft
             * .com/en-us/library/ms537503(v=vs.85).aspx
             */
            if (userAgentStr.contains("Windows NT 6.2")) { // Windows 8
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "8", null); // 判断浏览器
            } else if (userAgentStr.contains("Windows NT 6.1")) { // Windows 7
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "7", null);
            } else if (userAgentStr.contains("Windows NT 6.0")) { // Windows Vista
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "Vista", null);
            } else if (userAgentStr.contains("Windows NT 5.2")) { // Windows XP x64
                // Edition
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "XP", "x64 Edition");
            } else if (userAgentStr.contains("Windows NT 5.1")) { // Windows XP
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "XP", null);
            } else if (userAgentStr.contains("Windows NT 5.01")) { // Windows 2000,
                // Service Pack 1
                // (SP1)
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "2000", "SP1");
            } else if (userAgentStr.contains("Windows NT 5.0")) { // Windows 2000
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "2000", null);
            } else if (userAgentStr.contains("Windows NT 4.0")) { // Microsoft
                // Windows NT 4.0
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "NT 4.0", null);
            } else if (userAgentStr.contains("Windows 98; Win 9x 4.90")) { // Windows
                // Millennium
                // Edition
                // (Windows
                // Me)
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "ME", null);
            } else if (userAgentStr.contains("Windows 98")) { // Windows 98
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "98", null);
            } else if (userAgentStr.contains("Windows 95")) { // Windows 95
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "95", null);
            } else if (userAgentStr.contains("Windows CE")) { // Windows CE
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, "CE", null);
            } else { // windows其他类型
                return judgeBrowser(userAgentStr, PLATFORM_WINDOWS, null, null);
            }
        } else if (userAgentStr.contains("Mac OS X")) {
            /*
             * ******** 苹果系列 ******** iPod - Mozilla/5.0 (iPod; U; CPU iPhone OS
             * 4_3_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like
             * Gecko) Version/5.0.2 Mobile/8G4 Safari/6533.18.5 iPad -
             * Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us)
             * AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4
             * Mobile/7B334b Safari/531.21.10 iPad2 - Mozilla/5.0 (iPad; CPU OS
             * 5_1 like Mac OS X; en-us) AppleWebKit/534.46 (KHTML, like Gecko)
             * Version/5.1 Mobile/9B176 Safari/7534.48.3 iPhone 4 - Mozilla/5.0
             * (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us)
             * AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293
             * Safari/6531.22.7 iPhone 5 - Mozilla/5.0 (iPhone; CPU iPhone OS
             * 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko)
             * Version/5.1 Mobile/9A334 Safari/7534.48.3
             * 判断依据:http://www.useragentstring.com/pages/Safari/
             * 参考:http://stackoverflow
             * .com/questions/7825873/what-is-the-ios-5-0-user-agent-string
             * 参考:http
             * ://stackoverflow.com/questions/3105555/what-is-the-iphone-4
             * -user-agent
             */
            if (userAgentStr.contains("iPod")) {
                return judgeBrowser(userAgentStr, "iPod", null, null);
            } else if (userAgentStr.contains("iPhone")) {
                return judgeBrowser(userAgentStr, "iPhone", null, null);
            } else if (userAgentStr.contains("Macintosh")) { // mac
                return judgeBrowser(userAgentStr, "Macintosh", null, null);
            } else { // Mac OS X其他类型
                return judgeBrowser(userAgentStr, "Mac OS X", null, null);
            }
        }
        return null;
    }

    /**
     * 用途：根据客户端 User Agent Strings 判断其浏览器 if 判断的先后次序：
     * 根据浏览器的用户使用量降序排列，这样对于大多数用户来说可以少判断几次即可拿到结果： >>Browser:Chrome > FF > IE >
     * ...
     *
     * @param userAgentStr
     *            :user agent
     * @param platformType
     *            :平台
     * @param platformSeries
     *            :系列
     * @param platformVersion
     *            :版本
     * @return UserAgent对象
     */
    private static UserAgent judgeBrowser(String userAgentStr, String platformType,
                                          String platformSeries, String platformVersion) {
        if (userAgentStr.contains(BROWSER_CHROME)) {
            /*
             * *********** Chrome 系列 *********** Chrome 24.0.1295.0 -
             * Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.15 (KHTML,
             * like Gecko) Chrome/24.0.1295.0 Safari/537.15 Chrome 24.0.1292.0 -
             * Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.14 (KHTML,
             * like Gecko) Chrome/24.0.1292.0 Safari/537.14 Chrome 24.0.1290.1 -
             * Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.13
             * (KHTML, like Gecko) Chrome/24.0.1290.1 Safari/537.13
             * 判断依据:http://www.useragentstring.com/pages/Chrome/
             */
            String temp = userAgentStr.substring(userAgentStr.indexOf("Chrome/") + 7);
            // 拿到User
            // Agent
            // String
            // "Chrome/"
            // 之后的字符串,结果形如"24.0.1295.0 Safari/537.15"或"24.0.1295.0"
            String chromeVersion = null;
            if (!temp.contains(" ")) { // temp形如"24.0.1295.0"
                chromeVersion = temp;
            } else { // temp形如"24.0.1295.0 Safari/537.15"
                chromeVersion = temp.substring(0, temp.indexOf(" "));
            }
            return new UserAgent(BROWSER_CHROME, chromeVersion, platformType, platformSeries, platformVersion);
        } else if (userAgentStr.contains(BROWSER_FIREFOX)) {
            /*
             * ******* FF 系列 ******* Firefox 16.0.1 - Mozilla/5.0 (Windows NT
             * 6.2; Win64; x64; rv:16.0.1) Gecko/20121011 Firefox/16.0.1 Firefox
             * 15.0a2 - Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716
             * Firefox/15.0a2 Firefox 15.0.2 - Mozilla/5.0 (Windows NT 6.2;
             * WOW64; rv:15.0) Gecko/20120910144328 Firefox/15.0.2
             * 判断依据:http://www.useragentstring.com/pages/Firefox/
             */
            String temp = userAgentStr.substring(userAgentStr.indexOf("Firefox/") + 8);
            // 拿到User
            // Agent
            // String
            // "Firefox/"
            // 之后的字符串,结果形如"16.0.1 Gecko/20121011"或"16.0.1"
            String ffVersion = null;
            if (!temp.contains(" ")) { // temp形如"16.0.1"
                ffVersion = temp;
            } else { // temp形如"16.0.1 Gecko/20121011"
                ffVersion = temp.substring(0, temp.indexOf(" "));
            }
            return new UserAgent(BROWSER_FIREFOX, ffVersion, platformType, platformSeries, platformVersion);
        } else if (userAgentStr.contains("MSIE")) {
            /*
             * ******* IE 系列 ******* MSIE 10.0 - Internet Explorer 10 MSIE 9.0 -
             * Internet Explorer 9 MSIE 8.0 - Internet Explorer 8 or IE8
             * Compatibility View/Browser Mode MSIE 7.0 - Windows Internet
             * Explorer 7 or IE7 Compatibility View/Browser Mode MSIE 6.0 -
             * Microsoft Internet Explorer 6
             * 判断依据:http://msdn.microsoft.com/en-us
             * /library/ms537503(v=vs.85).aspx
             */
            if (userAgentStr.contains("MSIE 10.0")) { // Internet Explorer 10
                return new UserAgent(BROWSER_IE, "10", platformType, platformSeries, platformVersion);
            } else if (userAgentStr.contains("MSIE 9.0")) { // Internet Explorer9
                return new UserAgent(BROWSER_IE, "9", platformType, platformSeries, platformVersion);
            } else if (userAgentStr.contains("MSIE 8.0")) { // Internet Explorer8
                return new UserAgent(BROWSER_IE, "8", platformType, platformSeries, platformVersion);
            } else if (userAgentStr.contains("MSIE 7.0")) { // Internet Explorer7
                return new UserAgent(BROWSER_IE, "7", platformType, platformSeries, platformVersion);
            } else if (userAgentStr.contains("MSIE 6.0")) { // Internet Explorer6
                return new UserAgent(BROWSER_IE, "6", platformType, platformSeries, platformVersion);
            }
        } else { // 暂时支持以上三个主流.其它浏览器,待续...
            return new UserAgent(null, null, platformType, platformSeries, platformVersion);
        }
        return null;
    }
}
